home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
brush.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
8KB
|
433 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* brush -
* draw geometric brushes for impression
*
* Paul Haeberli - 1987
*
* exports
*
void ssortho(xsize, ysize)
void ssdrawinit()
void ssdraw(ss)
void wrapssdraw(ss)
void ssblob(ss,x,y,xsize,ysize)
void ssline(x1,y1,x2,y2,width) NOT IMPLEMENTED
void drawstroke(s)
void ssbrushobj(myobj)
void ssconesides(n)
void drawcone()
void tmrect(x0,y0,x1,y1)
void drawline(x0,y0,x1,y1)
void myc4f(c)
void mycpack(c)
void blendon( )
void blendoff( )
*
*/
#include "math.h"
#include "values.h"
#include "gl.h"
#include "ss.h"
#include "texture.h"
#include "obj.h"
#include "gfxmach.h"
#define NBRISTLES (3)
#define WIDTH (0.25)
float frand();
static float tmxscale, tmyscale;
static int vpxsize, vpysize;
static int npnts = 25;
static int sqnpnts = 5;
static object *obj;
static float posxscale = 1.0;
static float posyscale = 1.0;
void drawstroke();
void drawcone();
void tmrect();
void drawline();
void mycpack();
void blendon();
void ssortho(xsize, ysize)
int xsize, ysize;
{
float xmax, ymax;
if(xsize>ysize) {
xmax = 1.0;
ymax = (float)ysize/xsize;
} else {
xmax = (float)xsize/ysize;
ymax = 1.0;
}
posxscale = xmax;
posyscale = ymax;
renderortho(0.0,xmax,0.0,ymax,-1.0,1.0);
ortho(0.0,xmax,0.0,ymax,-1.0,1.0);
blendon();
}
void ssdrawinit()
{
short x0, x1, y0, y1;
getviewport(&x0,&x1,&y0,&y1);
vpxsize = x1-x0+1;
tmxscale = 1.0/vpxsize;
vpysize = y1-y0+1;
tmyscale = 1.0/vpysize;
npnts = 12.0*5.0*(vpxsize*vpxsize)/(1000.0*1000.0);
sqnpnts = sqrt((float)npnts)+0.5;
}
void ssdraw(ss)
sampleset *ss;
{
sample *s;
ssdrawinit();
s = ss->head;
while(s) {
drawstroke(s);
s = s->next;
}
}
void wrapssdraw(ss)
sampleset *ss;
{
int x, y;
sample *s;
ssdrawinit();
s = ss->head;
while(s) {
for(y=0; y<3; y++) {
for(x=0; x<3; x++) {
pushmatrix();
translate(x-1.0,y-1.0,0.0);
drawstroke(s);
popmatrix();
}
}
s = s->next;
}
}
void ssblob(ss,x,y,xsize,ysize)
sampleset *ss;
float x, y, xsize, ysize;
{
pushmatrix();
translate(x,y,0.0);
scale(xsize,ysize,1.0);
translate(-0.5,-0.5,0.0);
ssdraw(ss);
popmatrix();
}
void ssline(x1,y1,x2,y2,width)
{
}
void drawstroke(s)
sample *s;
{
float currad;
float curdir;
float radscale, rad;
float by, ydelt;
int i;
float xpos, ypos;
int x, y, nb;
pushmatrix();
translate(posxscale*(float)s->xpos/(float)POSSCALE,
posyscale*(float)s->ypos/(float)POSSCALE,0.0);
radscale = 2.0/768.0;
currad = radscale*s->SAMPLE_SIZE;
rad = currad/2.0;
i = s->SAMPLE_DIR;
curdir = (i*360.0)/256.0;
mycpack((s->a<<24)+(s->b<<16)+(s->g<<8)+(s->r<<0));
switch(s->SAMPLE_SHAPE) {
case CIRCLES:
fillcirc(0.0,0.0,rad/2.0);
break;
case SQUARES:
rot(curdir,'z');
fillrect(-rad/2.0,-rad/2.0,rad/2.0,rad/2.0);
break;
case STROKES:
rot(curdir,'z');
fillrect(-rad,-rad/4.0,rad,rad/4.0);
break;
case LONGSTROKES:
rot(curdir,'z');
fillrect(-rad,-rad/16.0,rad,rad/16.0);
break;
case LINES:
rot(curdir,'z');
scale(rad,rad,1.0);
by = -WIDTH/2.0;
ydelt = (WIDTH)/(NBRISTLES-1);
for(i=0; i<NBRISTLES; i++) {
fillrect(-1.0/2.0+(frand()/2.0),by-ydelt/16.0,1.0/2.0+(frand()/2.0),by+ydelt/16.0);
by += ydelt;
}
break;
case SCATTER:
scale(rad,rad,1.0);
for(i=npnts; i--;) {
xpos = frand()-0.5;
ypos = frand()-0.5;
pnt2(xpos,ypos);
}
break;
case LONGSCATTER:
rot(curdir,'z');
scale(rad,rad,1.0);
for(i=npnts; i--;) {
xpos = 3.0*(frand()-0.5);
ypos = 0.25*(frand()-0.5);
pnt2(xpos,ypos);
}
break;
case SCATTERPOLY:
scale(rad,rad,1.0);
for(i=0; i<20; i++) {
xpos = frand()-0.5;
ypos = frand()-0.5;
fillrect(xpos-0.05,ypos-0.05,xpos+0.05,ypos+0.05);
}
break;
case CONE:
drawcone();
break;
case FINELINES:
rot(curdir,'z');
scale(rad,rad,1.0);
by = -WIDTH/2.0;
ydelt = (WIDTH)/(NBRISTLES-1);
for(i=0; i<NBRISTLES; i++) {
drawline(-1.0/2.0+(frand()/5.0),by,1.0/2.0+(frand()/5.0),by);
by += ydelt;
}
break;
case ONELINE:
rot(curdir,'z');
drawline(-rad,0.0,rad,0.0);
break;
case NEEDLEPOINT:
scale(1.2,1.2,1.0);
rot(-45.0,'z');
fillrect(-rad/5.0,-rad/2.0,rad/5.0,rad/2.0);
break;
case TEXTUREMAP:
if(fasttm()) {
rot(curdir,'z');
tmrect(-rad,-rad/2.0,rad,rad/2.0);
}
break;
case MULTILINE:
rot(curdir,'z');
scale(2.0*rad/1.5,2.0*rad,1.0);
by = -WIDTH/2.0;
nb = 3.0*sqnpnts;
if(nb<1)
nb = 1;
by = -WIDTH/2.0;
ydelt = (WIDTH)/(nb-1);
for(i=0; i<nb; i++) {
drawline(-1.0/2.0+(frand()/5.0),by,1.0/2.0+(frand()/5.0),by);
by += ydelt;
}
break;
case MYOBJECT:
if(obj) {
rot(curdir,'z');
scale(rad,rad,1.0);
drawobj(obj);
}
}
popmatrix();
}
#define PYRSIZE (0.25)
static float tricoord[3][3];
static int firsted;
static int nsides = 30;
void ssbrushobj(myobj)
object *myobj;
{
obj = myobj;
}
void ssconesides(n)
int n;
{
nsides = n;
firsted = 0;
}
void drawcone()
{
int i;
int sc, r, g, b;
if(!firsted) {
tricoord[0][0] = 0.0;
tricoord[0][1] = 0.0;
tricoord[0][2] = 1.0;
tricoord[1][0] = PYRSIZE*sin(0*(2*M_PI)/nsides);
tricoord[1][1] = PYRSIZE*cos(0*(2*M_PI)/nsides);
tricoord[1][2] = 0.0;
tricoord[2][0] = PYRSIZE*sin(1*(2*M_PI)/nsides);
tricoord[2][1] = PYRSIZE*cos(1*(2*M_PI)/nsides);
tricoord[2][2] = 0.0;
firsted = 1;
}
pushmatrix();
for(i=0; i<nsides; i++) {
bgnpolygon();
v3f(tricoord[0]);
v3f(tricoord[1]);
v3f(tricoord[2]);
endpolygon();
rot(360.0/nsides,'z');
}
popmatrix();
}
static int tmfirsted;
void tmrect(x0,y0,x1,y1)
float x0,y0,x1,y1;
{
vect t, v;
if(!tmfirsted) {
textureread("brush.rgba",1);
tmfirsted = 1;
}
settexture(1);
bgnpolygon();
t.x = 0.0;
t.y = 0.0;
myt2f(&t);
v.x = x0;
v.y = y0;
v2f((float *)&v);
t.x = 1.0;
t.y = 0.0;
myt2f(&t);
v.x = x1;
v.y = y0;
v2f((float *)&v);
t.x = 1.0;
t.y = 1.0;
myt2f(&t);
v.x = x1;
v.y = y1;
v2f((float *)&v);
t.x = 0.0;
t.y = 1.0;
myt2f(&t);
v.x = x0;
v.y = y1;
v2f((float *)&v);
endpolygon();
settexture(0);
}
void drawline(x0,y0,x1,y1)
float x0,y0,x1,y1;
{
float v[2];
bgnline();
v[0] = x0;
v[1] = y0;
v2f(v);
v[0] = x1;
v[1] = y1;
v2f(v);
endline();
}
void myc4f(c)
float *c;
{
int r, g, b;
if(gfxmachine() == MACH4D8) {
r = 255.9*c[0];
g = 255.9*c[1];
b = 255.9*c[2];
rgbi(r,g,b);
} else
c4f(c);
}
void mycpack(c)
long c;
{
int r, g, b, i;
if(gfxmachine() == MACH4D8) {
r = (c>>0)&0xff;
g = (c>>8)&0xff;
b = (c>>16)&0xff;
i = rgbi(r,g,b);
} else
cpack(c);
}
void blendon( )
{
int mach;
subpixel(1);
mach = gfxmachine();
if(getgdesc(GD_BLEND) && getgdesc(GD_BITS_NORM_SNG_RED)>6) {
blendfunction(BF_SA,BF_MSA);
linesmooth(SML_ON);
}
}
void blendoff()
{
int mach;
mach = gfxmachine();
if(getgdesc(GD_BLEND) && getgdesc(GD_BITS_NORM_SNG_RED)>6) {
blendfunction(BF_ONE,BF_ZERO);
linesmooth(SML_OFF);
}
}